home *** CD-ROM | disk | FTP | other *** search
- /* standard begin
- */
-
- #define MAXTERM 30
-
- #include <stdio.h>
- #ifdef AMIGA
- #include <gfxamiga.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #else
- #include <gfx.h>
- #endif
-
- float *spc,*err,*tim;
-
- double x,y;
- double Pi = 3.1415927,
- Gs = 2.0,
- k = 1.38062E-23,
- Mu0 = 1.256637E-6,
- MuB = 9.2741E-24,
- gI = 0.06,
- Nq = 4.0,
- l = 3.0,
- Nel = 5.0,
- J_grund = 0.0,
- Fak_BN = 0.0, /* must be set within programm */
- R_mittel = 0.0, /* must be set within programm */
- B_core = 10.0,
- Tbeg = 50.0,
- Tend = 1000.0,
- Tstep = 10.0;
-
- double *EJf,
- *Lges,
- *Sges,
- *Jges;
-
- double *sum1,
- *sum2,
- *sum3;
-
- double CurieTerm,
- VanVleckTerm;
-
- int NTerm = 0,
- Flag_1dT = 1;
-
- char *fnam;
-
- help()
- {
- printf("this programm calculates the paramagnetic enhancement factor for\n");
- printf("various ions at various temperatures.\n");
- printf("B_HF [-r file] [-T] [-Ts n.m] [-Te n.m] [-Ti n.m] [-go]\n");
- printf(" -r file reads data from file\n");
- printf(" -T generates spectrum as function of direct Temperature\n");
- printf(" -Ts n.m sets start temperature\n");
- printf(" -Te n.m sets end temperature\n");
- printf(" -Ti n.m sets temperature increment\n");
- printf(" -go suppress interactive mode\n");
- }
-
- double dabs(x)
- double x;
- {
- if(x >= 0.0) return(x);
- return(-1.0 * x);
- }
-
- double Energy(E,us,dir)
- double E;
- char *us;
- int dir;
- {
- double c;
-
- c = 0.0;
- if(strcmp(us,"J") == 0) c = 1.0;
- if(strcmp(us,"K") == 0) c = 1.38062E-23;
- if(strcmp(us,"eV") == 0) c = 1.60219E-19;
- if(strcmp(us,"erg") == 0) c = 1.0E-7;
- if(c == 0.0) {
- fprintf(stderr,"unrecognised Energy unit :%s\n",us);
- return(E);
- }
- if(dir < 0) c = 1/c;
- return(c * E);
- }
-
- double ReCuR(R,us,dir)
- double R;
- char *us;
- int dir;
- {
- double c;
-
- c = 0.0;
- if(strcmp(us,"m") == 0) c = 1.0;
- if(strcmp(us,"cm") == 0) c = 1.0E6;
- if(strcmp(us,"A") == 0) c = 1.0E30;
- if(strcmp(us,"a.u.") == 0) c = 6.748321E30;
- if(c == 0.0) {
- fprintf(stderr,"unrecognised radius unit :%s\n",us);
- return(R);
- }
- if(dir < 0) c = 1/c;
- return(c * R);
- }
-
- double Tesla(E,us,dir)
- double E;
- char *us;
- int dir;
- {
- double c;
-
- c = 0.0;
- if(strcmp(us,"T") == 0) c = 1.0;
- if(strcmp(us,"KG") == 0) c = 0.1;
- if(c == 0.0) {
- fprintf(stderr,"unrecognised Magnetic Field unit :%s\n",us);
- return(E);
- }
- if(dir < 0) c = 1/c;
- return(c * E);
- }
-
-
- double v(l,Lges,Sges)
- double l,Lges,Sges;
- {
- double erg;
-
- erg = (4.0 * Sges - (2.0 * l + 1)) / ((2.0 * l - 1.0) * ( 2.0 * l + 3.0) * Sges * ( 2.0 * Lges - 1.0));
- return(erg);
- }
-
- double meJNJ(l,Lges,Sges,J)
- double l,Lges,Sges,J;
- {
- double erg,JJ,LL,SS;
-
- JJ = J * (J + 1.0);
- LL = Lges * (Lges + 1.0);
- SS = Sges * (Sges + 1.0);
- if(J == 0) {
- erg = 1.0 + v(l,Lges,Sges) * 0.5 * Gs * (3.0 * JJ - 2.0 * LL - 3.0 * SS - 1.0);
- } else {
- erg = 3.0 * JJ - 2.0 * LL - 3.0 * SS - (3.0 * JJ - LL + SS) * (3.0 * JJ - LL - 3.0 * SS) / (4.0 * JJ);
- erg = erg * v(l,Lges,Sges) * 0.5 * Gs;
- erg = erg + (JJ + LL - SS)/(2.0 * JJ);
- }
- return(erg);
- }
-
- double sqr(x)
- double x;
- {
- return(x * x);
- }
-
- double meJAJ(Lges,Sges,J)
- double Lges,Sges,J;
- {
- double erg,JJ,LL,SS;
-
- JJ = J * (J + 1.0);
- LL = Lges * (Lges + 1.0);
- SS = Sges * (Sges + 1.0);
-
- if(J == 0.0) return(Gs);
- erg = 1.0 + (Gs - 1) * (JJ + SS - LL) / (2.0 * JJ);
- return(erg);
- }
-
- double Bj(l,Lges,Sges,J)
- double l,Lges,Sges,J;
- {
- double erg;
-
- erg = (sqr(Sges + Lges + 1.0) - J * J) * (J * J - sqr(Lges - Sges))/(6.0 * J);
- erg = erg * (1.0 + v(l,Lges,Sges) * (3 * J * J - Lges * (Lges + 1.0) - 3.0 * Sges * (Sges + 1.0)) / 2.0);
- return(erg);
- }
-
- double Calc_Bc(gj,J)
- double gj,J;
- {
- return(-1.0 * B_core * (gj - 1) * J);
- }
-
- calc_ELSJ()
- {
- double Sg,Lg,x1,x2;
- int i;
-
- Sg = 0.5 * ((2.0 * l + 1.0) - dabs(2.0 * l + 1.0 - Nel));
- Lg = Sg * dabs(2.0 * l + 1.0 - Nel);
- J_grund = Sg * dabs(2.0 * l - Nel);
- Fak_BN = 2.0 * MuB * Mu0 * R_mittel / (4.0 * Pi);
- for(i = 0; i < MAXTERM; i++) {
- Lges[i] = Lg;
- Sges[i] = Sg;
- }
- x1 = dabs(Lg - Sg);
- x2 = Lg + Sg;
- NTerm = (int) (x2 - x1 + 1.00001);
- for(i = 0; i < NTerm; i++) Jges[i] = (x1 + (double)i);
- }
-
-
- double Bi0(J)
- double J;
- {
- double erg;
- int n;
-
- n = 0;
-
- erg = Fak_BN * meJNJ(l,Lges[n],Sges[n],J) * J;
- erg = erg + Calc_Bc(meJAJ(Lges[n],Sges[n],J),J);
- return(erg);
- }
-
- double dexp(x)
- double x;
- {
- double n,fak,px,erg,last;
-
- fak = 1.0; px = 1.0; n = 0.0; erg = 1.0; last = 0.0;
- while(erg != last) {
- last = erg;
- n = n + 1.0; fak = fak * n; px = px * x;
- erg = erg + px / fak;
- if(n > 100.0) break;
- }
- return(erg);
- }
-
- double Ehoch(x)
- double x;
- {
- if(x > 0.0) {
- if(x > 500.0) return(dexp(500.0)); else return(dexp(x));
- } else {
- if(x < -500.0) return(0.0); else return(dexp(x));
- }
- }
-
- /* initialize sum1, sum2, sum3 */
- sum_init()
- {
- double J, gj, JBJ, JBJ1, f1, f2, Sg, Lg;
- double dif;
- int i;
-
- for(i = 0; i < MAXTERM; i++) {
- sum1[i] = 0.0;
- sum2[i] = 0.0;
- sum3[i] = 0.0;
- }
-
- for(i = 0; i < NTerm; i++) {
-
- J = Jges[i]; Lg = Lges[i]; Sg = Sges[i];
-
- gj = meJAJ(Lg,Sg,J);
- JBJ = Fak_BN * meJNJ(l,Lg,Sg,J);
- f1 = (2.0 * J + 1.0) * gj * MuB * (J + 1.0) * (JBJ * J + Calc_Bc(gj,J)) / (3.0 * k);
- sum1[i]= f1;
-
- if((i > 0) && (J != 0.0)) {
- JBJ1 = Fak_BN * Bj(l,Lg,Sg,J);
- dif = EJf[i] - EJf[i-1];
- f2 = MuB * JBJ1 / dif;
- sum2[i] = f2;
- }
-
- sum3[i] = (2.0 * J + 1.0);
- }
- }
-
- double Beta(T)
- double T;
- {
- double s1, s2, s3, kT, EXP_EJdkT;
- int i;
-
- kT = k * T; s1 = 0.0; s2 = 0.0; s3 = 0.0;
- for(i = 0; i < NTerm; i++) {
- EXP_EJdkT = Ehoch(-1.0 * EJf[i] / kT);
- /*
- printf("i = %d , EJ/kt = %f , Exp(EJ/kT) = %f sum1[i] = %f\n",i,EJf[i]/kT,EXP_EJdkT,sum1[i]);
- */
- s1 = s1 + sum1[i] * EXP_EJdkT / T;
- if(i > 0) {
- s2 = s2 + sum2[i] * (Ehoch(-1.0 * EJf[i-1] / kT) - EXP_EJdkT);
- /*
- printf("s2 = %-E , sum2[%d] = %-E \n",s2,i,sum2[i]);
- */
- }
- s3 = s3 + sum3[i] * EXP_EJdkT;
- }
- /*
- printf("s1 = %f , s2 = %f , s3 = %f\n",s1,s2,s3);
- */
- CurieTerm = 1.0E99;
- VanVleckTerm = 1.0E99;
- if(s3 != 0.0) {
- CurieTerm = s1 / s3;
- VanVleckTerm = s2 / s3;
- return(1.0 + (s1 - s2) / s3);
- } else {
- return(1.0E99);
- }
- }
-
- generate_spectrum(flag)
- int flag;
- {
- int i;
- double T;
- float *curie, *vanvleck;
-
- if(flag == 2) {
- curie = (float *) calloc(_MAXSPCLEN,sizeof(float));
- vanvleck = (float *) calloc(_MAXSPCLEN,sizeof(float));
- }
- i = 0; T = Tbeg;
- while(T < Tend) {
- spc[i] = (float) Beta(T);
- err[i] = 0.0;
- tim[i] = (float) T; if(Flag_1dT == 1) tim[i] = (float) (1.0 / T);
- if(flag == 2) {
- curie[i] = CurieTerm;
- vanvleck[i] = VanVleckTerm;
- }
- T = T + Tstep; i = i + 1;
- if(i > _MAXSPCLEN) break;
- }
- unlink("Curie.spc");
- unlink("Curie.err");
- unlink("Curie.tim");
- unlink("VanVleck.spc");
- unlink("VanVleck.err");
- unlink("VanVleck.tim");
- writespec("BHF_out",spc,err,i,2,"B_HF-output");
- writespec("BHF_out.tim",tim,err,i,2,"B_HF-output");
- if(flag == 2) {
- writespec("Curie",curie,err,i,2,"Curie Term");
- writespec("Curie.tim",tim,err,i,2,"Curie Term");
- writespec("VanVleck",vanvleck,err,i,2,"Van Vleck Term");
- writespec("VanVleck.tim",tim,err,i,2,"Van Vleck Term");
- free(curie); free(vanvleck);
- }
- }
-
- plot_spectrum()
- {
- FILE *fp;
-
- SysCall("lise:ash bhf_out -v -pag");
- fp = fopen("Curie.spc","r");
- if(fp != NULL) {
- SysCall("lise:ash Curie -p 1 -1 -v -pag");
- fclose(fp);
- }
- fp = fopen("VanVleck.spc","r");
- if(fp != NULL) {
- SysCall("lise:ash VanVleck -p 1 -2 -v");
- fclose(fp);
- }
- }
-
-
- /* interactive Beta table */
- table()
- {
- char *s;
- int i;
- double T,y;
-
- s = (char *) malloc(100);
- while(1 == 1) {
- printf("next temperature (or Just return to leave):"); fflush(stdout);
- fgets(s,80,stdin);
- if(s[0] == 10) break;
- sscanf(s,"%lf",&T);
- y = Beta(T);
- printf("CurieTerm = %-E , VanVleckTerm = %-E\n",CurieTerm,VanVleckTerm);
- printf("ß(%f) = %-E\n",T,y);
- }
- free(s);
- }
-
- show_faktor()
- {
- double J, gj, JBJ, JBJ1, f1, f2, Sg, Lg;
- double dif;
- int i;
-
- for(i = 0; i < MAXTERM; i++) {
- sum1[i] = 0.0;
- sum2[i] = 0.0;
- sum3[i] = 0.0;
- }
-
- for(i = 0; i < NTerm; i++) {
-
- J = Jges[i]; Lg = Lges[i]; Sg = Sges[i];
-
- gj = meJAJ(Lg,Sg,J);
- printf("gj(L=%2.2f,S=%2.2f,J=%2.2f) = %f\n",Lg,Sg,J,gj);
- JBJ = meJNJ(l,Lg,Sg,J);
- printf("<J|N|J>(l=%2.2f,L=%2.2f,S=%2.2f,J=%2.2f) = %f\n",l,Lg,Sg,J,JBJ);
- JBJ = Fak_BN * JBJ;
- f1 = (2.0 * J + 1.0) * gj * MuB * (J + 1.0) * (JBJ * J + Calc_Bc(gj,J)) / (3.0 * k);
-
- if((i > 0) && (J != 0.0)) {
- JBJ1 = Bj(l,Lg,Sg,J);
- printf("gj-1(l=%2.2f,L=%2.2f,S=%2.2f,J=%2.2f) = %f\n",l,Lg,Sg,J,JBJ1);
- JBJ1 = Fak_BN * JBJ1;
- dif = EJf[i] - EJf[i-1];
- f2 = MuB * JBJ1 / dif;
- /*
- printf("EJ[%d] = %-E , dif = %-E , JBJ1 = %-E\n",i,EJf[i],dif,JBJ1);
- */
- }
- }
- }
-
- double edit_double(text,x)
- char *text;
- double x;
- {
- char *s;
- double y;
-
- s = (char *) malloc(100);
- printf("%s = %f ?",text,x); fflush(stdout);
- fgets(s,80,stdin);
- y = x;
- if(s[0] != 10) sscanf(s,"%lf",&y);
- free(s);
- return(y);
- }
-
- ask_data()
- {
- int i,n;
- double x,y;
- char s[4];
-
- /* gI = edit_double("Kern g Faktor",gI); */
- Nq = edit_double("Hauptquantenzahl",Nq);
- l = edit_double("Bahndrehimpuls (s=0,p=1,d=2,f=3)",l);
- Nel = edit_double("Anzahl der Elektronen in der Schale",Nel);
- x = ReCuR(R_mittel,"a.u.",-1);
- x = edit_double("<r-3> in atomaren Einheiten",x);
- R_mittel = ReCuR(x,"a.u.",1);
- x = Tesla(B_core,"T",-1);
- x = edit_double("Corepolarisation in Tesla",x);
- B_core = Tesla(x,"T",1);
-
- printf("calculating defaults ? (Y/N)"); fflush(stdout);
- fgets(s,2,stdin);
- if((s[0] == 'y') || (s[0] == 'Y')) calc_ELSJ();
-
- x = (double)NTerm;
- NTerm = (int) (0.00001 + edit_double("Anzahl der Terme",x));
- for(i = 0; i < NTerm; i++) {
- x = Energy(EJf[i],"K",-1);
- printf("%d : J = %f S = %f L = %f EJ = %f\n",i,Jges[i],Sges[i],Lges[i],x);
- Jges[i] = edit_double("J",Jges[i]);
- Lges[i] = edit_double("L",Lges[i]);
- Sges[i] = edit_double("S",Sges[i]);
- x = edit_double("EJ in Kelvin",x);
- EJf[i] = Energy(x,"K",1);
- }
- printf("pre calculating sums...\n");
- sum_init();
- printf("ready\n");
- }
-
- calculate_data()
- {
- int i,n;
- double x,y;
- int flag;
- char c,s[4];
-
- Tbeg = edit_double("Tbeg (Kelvin)",Tbeg);
- Tend = edit_double("Tend",Tend);
- Tstep = edit_double("Tstep",Tstep);
- flag = 1;
- printf("generate Curie curve and Van Vleck curve separately ? (Y/N)"); fflush(stdout);
- fgets(s,2,stdin); c = s[0];
- if((c == 'y') || (c == 'Y')) flag = 2;
- generate_spectrum(flag);
- }
-
- save_data()
- {
- FILE *fp;
- int i,n;
- double x;
- char *s;
-
- s = (char *) malloc(100);
- printf("saving to >%s< ?",fnam); fflush(stdout);
- fgets(s,80,stdin);
- if(s[0] != 10) {s[strlen(s)-1] = 0; strcpy(fnam,s);}
- free(s);
-
- fp = fopen(fnam,"w");
- if(fp == NULL) {
- fprintf(stderr,"could not open file for write: %s\n",fnam);
- return();
- }
-
- fprintf(fp,"%f\n",gI);
- fprintf(fp,"%f\n",Nq);
- fprintf(fp,"%f\n",l);
- fprintf(fp,"%f\n",Nel);
- fprintf(fp,"%f\n",J_grund);
- fprintf(fp,"%f\n",R_mittel);
- fprintf(fp,"%f\n",B_core);
- fprintf(fp,"%d\n",NTerm);
- for(i = 0; i < MAXTERM; i++) {
- fprintf(fp,"%f\n",Jges[i]);
- fprintf(fp,"%f\n",Lges[i]);
- fprintf(fp,"%f\n",Sges[i]);
- x = Energy(EJf[i],"K",-1);
- fprintf(fp,"%f\n",x);
- }
- fclose(fp);
- }
-
- load_data()
- {
- int i,n;
- char *s;
-
- s = (char *) malloc(100);
- printf("loading from >%s< ?",fnam); fflush(stdout);
- fgets(s,80,stdin);
- if(s[0] != 10) {s[strlen(s)-1] = 0; strcpy(fnam,s);}
- free(s);
- read_data();
- }
-
- read_data()
- {
- FILE *fp;
- int i,n;
- double x;
-
- fp = fopen(fnam,"r");
- if(fp == NULL) {
- fprintf(stderr,"could not open file for read: %s\n",fnam);
- printf("pre calculating sums...\n");
- sum_init();
- printf("ready\n");
- return();
- }
- fscanf(fp,"%lf",&gI);
- fscanf(fp,"%lf",&Nq);
- fscanf(fp,"%lf",&l);
- fscanf(fp,"%lf",&Nel);
- fscanf(fp,"%lf",&J_grund);
- fscanf(fp,"%lf",&R_mittel);
- fscanf(fp,"%lf",&B_core);
- fscanf(fp,"%d",&NTerm);
- for(i = 0; i < MAXTERM; i++) {
- fscanf(fp,"%lf",&Jges[i]);
- fscanf(fp,"%lf",&Lges[i]);
- fscanf(fp,"%lf",&Sges[i]);
- fscanf(fp,"%lf",&x);
- EJf[i] = Energy(x,"K",1);
- }
- fclose(fp);
- printf("pre calculating sums...\n");
- sum_init();
- printf("ready\n");
- }
-
- interactive()
- {
- int i, flag;
- char *s,c;
-
- s = (char *) malloc(100);
- flag = 1;
- while(flag == 1) {
- printf("<S>ave (data) <M>odify (data) <C>alculate (spectrum) <P>lot (spectrum)\n");
- printf("<L>oad (data) <F>lag (1/T toggle) <T>able (Beta(T)) <Q>uit\n");
- printf("<G> (gj,...)\n");
- fgets(s,80,stdin);
- c = s[0];
- switch(c) {
- case 'S': case 's': save_data(); break;
- case 'L': case 'l': load_data(); break;
- case 'M': case 'm': ask_data(); break;
- case 'C': case 'c': calculate_data(); break;
- case 'P': case 'p': plot_spectrum(); break;
- case 'F': case 'f': Flag_1dT = Flag_1dT ^ 1; break;
- case 'T': case 't': table(); break;
- case 'Q': case 'q': flag = 0; break;
- case 'G': case 'g': show_faktor(); break;
- default: printf("unknown command >%s<\n",s);
- }
- }
- free(s);
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int n,m,i,max;
- char *z;
-
- spc = (float *) calloc(_MAXSPCLEN,sizeof(float));
- err = (float *) calloc(_MAXSPCLEN,sizeof(float));
- tim = (float *) calloc(_MAXSPCLEN,sizeof(float));
- EJf = (double *) calloc(MAXTERM,sizeof(double));
- Lges = (double *) calloc(MAXTERM,sizeof(double));
- Sges = (double *) calloc(MAXTERM,sizeof(double));
- Jges = (double *) calloc(MAXTERM,sizeof(double));
- sum1 = (double *) calloc(MAXTERM,sizeof(double));
- sum2 = (double *) calloc(MAXTERM,sizeof(double));
- sum3 = (double *) calloc(MAXTERM,sizeof(double));
- z = (char *) malloc(80);
- fnam = (char *) malloc(80);
- strcpy(fnam,"BHF_dat");
-
- for(i = 0; i < MAXTERM; i++) EJf[i] = (double) (i * 1000);
-
- R_mittel = ReCuR(6.796,"a.u.",1);
- EJf[1] = Energy(1600.0,"K",1);
- B_core = 10.0;
- calc_ELSJ();
-
- if(checkopt(argc,argv,"-r",z)) strcpy(fnam,z);
- if(checkopt(argc,argv,"-T",z)) Flag_1dT = 0;
- if(checkopt(argc,argv,"-Ts",z)) sscanf(z,"%lf",&Tbeg);
- if(checkopt(argc,argv,"-Te",z)) sscanf(z,"%lf",&Tend);
- if(checkopt(argc,argv,"-Ti",z)) sscanf(z,"%lf",&Tstep);
-
- read_data();
- if(checkopt(argc,argv,"-go",z)) {
- generate_spectrum(1);
- } else {
- help();
- interactive();
- }
-
- free(fnam); free(z);
- free(sum1); free(sum2); free(sum3);
- free(Jges); free(Sges); free(Lges);
- free(EJf); free(tim); free(err); free(spc);
- }
-
- SysCall(str)
- char *str;
- {
- int i,n,m;
-
- #ifdef AMIGA
- struct FileHandle *input, *output;
-
- input = (struct FileHandle *) Open("nil:",MODE_OLDFILE);
- output = (struct FileHandle *) Open("nil:",MODE_NEWFILE);
- Execute(str,input,output);
- Close(input);
- Close(output);
- #endif
-
- #ifdef UNIX
- system(str);
- #endif
- }
-